/*
 * @Author: wuqingchun
 * @Date: 2024-12-03 19:48:03
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-12-03 20:27:59
 */
#ifndef __STRING_VIEW_H__
#define __STRING_VIEW_H__

#include <cstddef>
#include <cstring>
#include <type_traits>
#include <iostream>

namespace detail {
    constexpr bool const_check(bool condition) {
        return condition;
    }

    constexpr auto is_constant_evaluated(bool default_value = false) noexcept -> bool {
        // Workaround for incompatibility between libstdc++ consteval-based
        // std::is_constant_evaluated() implementation and clang-14.
        // https://github.com/fmtlib/fmt/issues/3247
        #if FMT_CPLUSPLUS >= 202002L && defined(_GLIBCXX_RELEASE) && \
            _GLIBCXX_RELEASE >= 12 &&                                \
            (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)
        ignore_unused(default_value);
        return __builtin_is_constant_evaluated();
        #elif defined(__cpp_lib_is_constant_evaluated)
        ignore_unused(default_value);
        return std::is_constant_evaluated();
        #else
        return default_value;
        #endif
    }
}

template <typename Char>
class basic_string_view {
public:
    /**
     * 使用 constexpr 修饰构造函数的主要目的是允许在编译时创建常量表达式对象，从而提高性能和安全性。
     * 这对于处理编译时常量数据、静态初始化和减少运行时开销非常有用。
     * 
     * noexcept 关键字则进一步确保该构造函数不会抛出异常，有助于编译器优化和提高运行时性能。
     * 
     */
    // 默认构造函数
    constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}

    // 从 const Char* 构造
    constexpr basic_string_view(const Char* s)
        : data_(s),
          size_(detail::const_check(std::is_same<Char, char>::value &&
                                    !detail::is_constant_evaluated(true))
                  ? std::strlen(reinterpret_cast<const char*>(s))
                  : std::char_traits<Char>::length(s)) {}

    // 其他成员函数
    constexpr size_t size() const {
        return size_;
    }

    constexpr const Char* data() const {
        return data_;
    }

private:
    const Char* data_;
    size_t size_;
};

int main(int argc, char** argv) 
{
    // 编译时常量初始化
    // constexpr basic_string_view<char> sv1 = "Hello, World!";
    basic_string_view<char> sv1 = "Hello, World!";
    std::cout << "String view 1: " << sv1.data() << " (size: " << sv1.size() << ")\n";

    // 运行时初始化
    const char* str = "Another string";
    basic_string_view<char> sv2(str);
    std::cout << "String view 2: " << sv2.data() << " (size: " << sv2.size() << ")\n";

    // 使用其他字符类型
    const wchar_t* wstr = L"Wide string";
    basic_string_view<wchar_t> sv3(wstr);
    std::cout << "String view 3: " << sv3.data() << " (size: " << sv3.size() << ")\n";

    return 0;
}


#endif //__STRING_VIEW_H__